#include "bookmanager.h"

bookmanager::bookmanager()
{
     //Nothing is here
    /********************
     *     ---   ---    *    
     *         |        *
     *         W        *
     ********************/
}

BookManageErrCode bookmanager::addbook(book _book)
{
    if(checkrepeat(_book))
        return BookManageErrCode::RepeatName;
    _book.ID = books.size() + 1;
    books.emplace_back(_book);
    return BookManageErrCode::SystemOK;
}

BookManageErrCode bookmanager::delbook(std::string name)
{
    uint32_t ID = findbookbyname(name);
    if(ID == 0)
        return BookManageErrCode::NameNotMatch;
    if(books[ID - 1].tobedel == 1)
        return BookManageErrCode::BookIsToBeDel;
    books[ID - 1].allowborrow = 0;
    if(books[ID - 1].borrownumber == 0)
    {
        books[ID - 1].deleted = 1;
        books[ID - 1].number = 0;
    }
    else
    {
        books[ID - 1].tobedel = 1;
    }
}

uint32_t bookmanager::findbookbyname(std::string _name)
{
    for(int i = 0;i < books.size(); i++)
    {
        if(books[i].name == _name)
            return i + 1;
    }
    return 0;
}

book* bookmanager::findbookbyID(uint32_t ID)
{
    return &(books[ID - 1]);
}

bool bookmanager::checkrepeat(book _book)
{
    for(book __book:books)
    {
        if(__book.name == _book.name)
            return 1;
    }
    return 0;
}

BookManageErrCode bookmanager::operator<<(book& _book)
{
    return addbook(_book);
}

BookManageErrCode bookmanager::borrowBook(std::string name, book& _book)
{
    uint32_t ID = findbookbyname(name);
    if(ID == 0)
        return BookManageErrCode::NameNotMatch;
    if(!books[ID - 1].allowborrow)
        return BookManageErrCode::NotAllowBorrow;
    _book = books[ID - 1];
    books[ID - 1].borrownumber += 1;
}

BookManageErrCode bookmanager::returnBook(book& _book)
{
    books[_book.ID - 1].borrownumber -= 1;
    if(books[_book.ID - 1].tobedel && books[_book.ID - 1].borrownumber == 0)
    {
        books[_book.ID - 1].tobedel = 0;
        books[_book.ID - 1].deleted = 1;
        books[_book.ID - 1].allowborrow = 0;
        books[_book.ID - 1].number = 0;
    }
    return SystemOK;
}

std::vector<SearchOutput> bookmanager::search(std::string name)
{
    std::vector<SearchOutput> retval;
    for(int i = 0;i < books.size();i++)
    {
        float confidence = 0;
        if(bookmanage::findConfidence(name,books[i],confidence))
        {
            SearchOutput val;
            val.confidance = confidence;
            val.ptr = &books[i];
            retval.emplace_back(val);
        }
    }
    return retval;
}

bool bookmanage::compare(SearchOutput& a,SearchOutput& b)
{
    return a.confidance > b.confidance;
}

bool bookmanage::findConfidence(std::string name,book ptr,float& confidence)
{
const std::string& bookName = ptr.name;
    
    // 计算字符串相似度
    int matchingChars = 0;
    for (std::size_t i = 0; i < name.length() && i < bookName.length(); i++) 
    {
        if (name[i] == bookName[i]) {
            matchingChars += 1;
        }
    }
    
    // 计算置信度
    float maxConfidence = static_cast<float>(std::min(name.length(), bookName.length())) / std::max(name.length(), bookName.length());
    confidence = static_cast<float>(matchingChars) / std::max(name.length(), bookName.length());
    
    const float threshold = 0.01;
    return confidence >= threshold;
}

BookManageErrCode bookmanager::borrowBook(book* ptr)
{
    ptr->borrownumber += 1;  
    return BookManageErrCode::SystemOK; 
}

BookManageErrCode bookmanager::returnBook(book* ptr)
{
    ptr->borrownumber -= 1;
    if(ptr->tobedel && ptr->borrownumber == 0)
    {
        ptr->deleted = 1;
        ptr->number = 0;
        ptr->tobedel = 0;
    }
    return BookManageErrCode::SystemOK;
}

void bookmanager::loadDataFromLocalDataBase(std::string path)
{
    std::fstream database(path);

    if(!database.is_open())
        return;
    int datasum;
    database >> datasum;
    for(int i = 0;i < datasum;i++)
    {
        std::string name;
        int number;
        database >> name;
        database >> number;
        book data(name,number);
        data.allowborrow = 1;
        books.emplace_back(data);
    }
}